<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <script>
        class Graph {
            vertexes = []
            edge = new Map()

            addVertexes(v) {
                this.vertexes.push(v)
                this.edge.set(v, [])
            }

            addEdge(v1, v2) {
                this.edge.get(v1).push(v2)
                this.edge.get(v2).push(v1)
            }

            toString() {
                let res = ''
                this.vertexes.forEach((vertex, index) => {
                    res += vertex + '->'
                    let vEdge = this.edge.get(vertex)
                    vEdge.forEach((edge) => {
                        res += edge + ' '
                    })
                    res += '\n'
                })
                return res
            }

            initColor() {
                let colors = []
                this.vertexes.forEach(item => {
                    colors[item] = 'white'
                })
                return colors
            }

            bfs(initV, handler) {
                console.log(this.edge)
                let colors = this.initColor()
                let queue = []
                queue.push(initV)

                while (queue.length !== 0) {
                    let v = queue.shift()
                    colors[v] = 'gray'
                    // console.log(colors)
                    // return

                    let vList = this.edge.get(v)
                    vList.forEach(edge => {
                        if (colors[edge] === 'white') {
                            colors[edge] = 'gray'
                            console.log(colors)
                            queue.push(edge)
                            console.log(queue)
                        }


                    })

                    handler(v)
                    colors[v] = 'black'
                }
            }

            dfs(v, handler) {
                let colors = this.initColor()
                this.dfsRecursion(v, colors, handler)
            }

            dfsRecursion(v, colors, handler) {
                colors[v] = 'gray'
                handler(v)

                let vEdges = this.edge.get(v)
                console.log(vEdges)
                vEdges.forEach(edge => {
                    if (colors[edge] === 'white') {
                        this.dfsRecursion(edge, colors, handler)
                    }
                })
                colors[v] = 'black'
            }
        }

        let g = new Graph()
        let vertexes = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J']
        vertexes.forEach(vertex => {
            g.addVertexes(vertex)
        })
        g.addEdge('A', 'B')
        g.addEdge('B', 'C')
        g.addEdge('D', 'E')
        g.addEdge('F', 'G')
        g.addEdge('G', 'F')
        g.addEdge('A', 'C')
        g.addEdge('A', 'E')
        g.addEdge('H', 'I')
        g.addEdge('J', 'H')
        g.addEdge('D', 'C')
        g.addEdge('B', 'H')
        console.log(g.toString())
        console.log(g.initColor())

        let str = ''
        g.bfs('A', v => {
            str += v
        })
        console.log(str)


        let str2 = ''
        g.dfs('A', (item) => {
            str2 += item
        })
        console.log(str2)
    </script>
</body>

</html>